<?php
// 应用公共文件
use think\Response;
use think\facade\Db;
use think\facade\Route;
use think\facade\Cookie;
use think\facade\Request;
use chillerlan\QRCode\QRCode;
use app\common\services\Auth;
use chillerlan\QRCode\QROptions;
use app\common\model\addon\Addons;
use hiduoke\services\facade\Snowflake;
use hiduoke\exception\MessageException;
use app\common\model\platform\PlatformApp;
use app\common\model\platform\PlatformAddon;
use app\common\model\platform\PlatformSetting;
use hiduoke\services\facade\WechatService as Ws;

if (!function_exists("error")) {
    /**
     * 错误返回值函数
     * @param int $code
     * @param string $message
     * @param string $data
     * @return array
     */
    function error($msg = '', $data = '', $code = -1)
    {
        return [
            'code' => $code,
            'msg'  => $msg,
            'data' => $data
        ];
    }
}

if (!function_exists("success")) {
    /**
     * 返回值函数
     * @param int $code
     * @param string $message
     * @param string $data
     * @return array
     */
    function success($msg = '', $data = '', $other = [], $code = 0)
    {
        return [
            'code'  => $code,
            'msg'   => $msg,
            'data'  => $data,
            'other' => $other
        ];
    }
}

if (!function_exists("get_tree_children")) {
    /**
     * 获取树形菜单
     * @param array $data
     * @param string $childrenName
     * @param string $keyName
     * @param string $pidName
     * @return array
     */
    function get_tree_children(array $data, string $childrenName = 'children', string $keyName = 'id', string $pidName = 'pid')
    {
        $list = array();
        foreach ($data as $value) {
            $list[$value[$keyName]] = $value;
        }
        $tree = array();
        foreach ($list as $item) {
            if (isset($list[$item[$pidName]])) {
                $list[$item[$pidName]][$childrenName][] = &$list[$item[$keyName]];
            } else {
                $tree[] = &$list[$item[$keyName]];
            }
        }
        return $tree;
    }
}

if (!function_exists("getAddonAuthTree")) {
    /**
     * 获取应用权限树
     * @param $auth
     * @return array
     */
    function getAddonAuthTree($auth)
    {
        $tree = [];
        foreach ($auth as $key => $value) {
            if (is_array($value)) {
                if (isset($value['title']) && isset($value['value'])) {
                    $temp = [
                        'key'      => $key,
                        'label'    => $value['title'] ?? '',
                        'children' => getAddonAuthTree($value['value'])
                    ];
                } else {
                    continue;
                }
            } else {
                $temp = [
                    'key'   => $key,
                    'label' => $value,
                ];
            }
            $tree[] = $temp;
        }
        return $tree;
    }
}

if (!function_exists('getAddonAuthList')) {
    function getAddonAuthList($auth)
    {
        $list = [];
        foreach ($auth as $key => $value) {
            $list[] = $key;
            if (is_array($value) && isset($value['title']) && isset($value['value'])) {
                $list = array_merge($list, getAddonAuthList($value['value']));
            }
        }
        return $list;
    }
}

if (!function_exists('copy_dirs')) {
    /**
     * 复制文件夹
     * @param string $source 源文件夹
     * @param string $dest 目标文件夹
     */
    function copy_dirs($source, $dest)
    {
        if (!is_dir($dest)) {
            mkdir($dest, 0755, true);
        }
        //参照 https://www.php.net/manual/en/recursivedirectoryiterator.getsubpathname.php
        $iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($source, RecursiveDirectoryIterator::SKIP_DOTS), RecursiveIteratorIterator::SELF_FIRST);
        foreach ($iterator as $item) {
            if ($item->isDir()) {
                $sonDir = $dest . "/" . $iterator->getSubPathName();
                if (!is_dir($sonDir)) {
                    mkdir($sonDir, 0755, true);
                }
            } else {
                copy($item, $dest . "/" . $iterator->getSubPathName());
            }
        }
    }

}

if (!function_exists('rm_dirs')) {
    /**
     * 删除文件夹
     * @param string $dirname 目录
     * @param bool $del_self 是否删除自身
     * @return boolean
     */
    function rm_dirs($dirname, $del_self = true)
    {
        if (!is_dir($dirname)) return false;
        $Iterator = new RecursiveDirectoryIterator($dirname, RecursiveDirectoryIterator::SKIP_DOTS);
        $files = new RecursiveIteratorIterator($Iterator, RecursiveIteratorIterator::CHILD_FIRST);
        foreach ($files as $fileinfo) {
            $todo = ($fileinfo->isDir() ? 'rmdir' : 'unlink');
            $todo($fileinfo->getRealPath());
        }
        if ($del_self) {
            @rmdir($dirname);
        }
        return true;
    }
}

if (!function_exists('to')) {
    /**
     * 跳转
     * @param $url
     */
    function to($url)
    {
        Header("HTTP/1.1 303 See Other");
        Header("Location: $url");
    }
}

if (!function_exists('get_url')) {
    /**
     * 获取当前地址
     * @return string
     */
    function get_url()
    {
        $request = Request::instance();
        return $request->url(true);
    }
}

if (!function_exists("get_host")) {
    /**
     * 获取当前域名
     * @return string
     */
    function get_host()
    {
        // 获取请求对象
        $request = Request::instance();
        // 获取协议（http 或 https）
        $protocol = $request->isSsl() ? 'https://' : 'http://';
        // 获取主机名（包括端口）
        $host = $request->host(true);
        // 组合成完整的域名地址
        $domainUrl = $protocol . $host;
        // 返回结果
        return $domainUrl;
    }
}

if (!function_exists("get_user")) {
    /**
     * 获取当前登录用户信息
     * @return array
     */
    function get_user()
    {
        $auth = new Auth();
        $token = request()->header('access-token', request()->post('access-token', Cookie::get('access-token')));
        $auth->init($token);
        return $auth->getUserinfo();
    }
}

if (!function_exists("get_addon")) {
    /**
     * @param $cookie bool 通过cookie获取应用标识
     * @param $request bool 通过request中间件获取应用标识
     * @param $route bool 通过路由获取应用标识
     * @return array|mixed|string|string[]
     */
    function get_addon($cookie = false, $request = true, $route = true)
    {
        global $_DK;
        if (isset($_DK['addon'])) {
            return $_DK['addon'];
        } else {
            $addon = input('addon', request()->header('addon-name', ""));
            if ($cookie) {
                $addon = $addon ?: Cookie::get('dk_addon', '');
            }
            if ($request) {
                $addon = $addon ?: request()->addon;
            }
            if (!$addon && $route) {
                $s = explode('/', request()->param('s'));
                $_addon = $s[1] ?? '';
                if (strpos($_addon, '_') !== false) {
                    $addon = $_addon;
                }
                $addon = str_replace('.html', '', $addon);
            }
            return $addon;
        }
    }
}

if (!function_exists("get_addon_token")) {
    /**
     * 获取应用token
     * @param $addon
     * @return string
     */
    function get_addon_token()
    {
        $addon_name = get_addon();
        $plaid = get_plaid();
        $addon_token = (new PlatformAddon())->where(['addon_name' => $addon_name, 'plaid' => $plaid])->value('token') ?? false;
        return $addon_token;
    }
}

if (!function_exists("get_plaid")) {
    /**
     * 获取当前平台ID
     * @param $cookie bool 是否从cookie中获取
     * @return int
     */
    function get_plaid($cookie = false)
    {
        global $_DK;
        if (isset($_DK['plaid'])) {
            return $_DK['plaid'];
        } else {
            $plaid = input('p', input('plaid', request()->header('plaid', 0)));
            if ($cookie && !$plaid) {
                $plaid = $plaid ?: Cookie::get('dk_plaid', 0);
            }
            return intval($plaid);
        }
    }
}

if (!function_exists("get_appid")) {
    /**
     * 获取当前小程序ID
     * @param $cookie bool 是否从cookie中获取
     * @return int
     */
    function get_appid($cookie = false)
    {
        global $_DK;
        if (isset($_DK['appid'])) {
            return $_DK['appid'];
        } else {
            $appid = input('a', input('appid', request()->header('appid', 0)));
            if ($cookie && !$appid) {
                $appid = $appid ?: Cookie::get('dk_appid', 0);
            }
            return intval($appid);
        }
    }
}

if (!function_exists("get_rand")) {
    /**
     * 获取随机数
     * @param $type
     * @param $number
     * @return string
     */
    function get_rand($type = 1, $number = 6)
    {
        $res = '';
        switch ($type) {
            case 1:
                //随机大写字母
                for ($i = 0; $i < $number; $i++) {
                    $res .= chr(rand(65, 90));
                }
                break;
            case 2:
                //随机小写字母
                for ($i = 0; $i < $number; $i++) {
                    $res .= chr(rand(97, 122));
                }
                break;
            case 0:
                //随机数字
                for ($i = 0; $i < $number; $i++) {
                    $res .= rand(0, 9);
                }
                break;
            case 3:
                //雪花函数
                $res = substr(Snowflake::id(), 0, $number);
                break;
            default:
                break;
        }
        return $res;
    }
}

if (!function_exists("make_code")) {
    /**
     * 生成二维码
     * @param $data string 二维码内容
     * @param $size int 二维码大小
     * @param $margin int 二维码边距
     * @param $level int 二维码容错级别
     */
    function make_code($data, $size = 5, $margin = 2, $level = QRCode::ECC_H)
    {
        $options = new QROptions([
            'quietzoneSize'    => intval($margin),
            'outputType'       => QRCode::OUTPUT_IMAGE_PNG,
            'eccLevel'         => $level,
            'scale'            => intval($size),
            'imageBase64'      => false,
            'imageTransparent' => false,
        ]);

        $im = (new QRCode($options))->render($data);
        $response = Response::create($im);
        $response->header(['Content-Type' => 'image/png' . '; charset=utf-8']);
        return $response->code(200);
    }
}

if (!function_exists("get_code")) {
    /**
     * 获取二维码
     * @param $data string 二维码内容
     * @param $size int 二维码大小
     * @param $margin int 二维码边距
     * @param $level string 二维码容错级别
     * @return string
     */
    function get_code($data, $size = 5, $margin = 2, $level = 'H')
    {
        $vars = [
            'data'   => $data,
            'size'   => $size,
            'margin' => $margin,
            'level'  => $level,
        ];
        return Route::buildUrl('/adminapi/common/qr', $vars)->domain(true)->build();
    }
}

if (!function_exists('get_app_agent')) {
    /**
     * 获取应用标识
     * @return string
     */
    function get_app_agent()
    {
        $agent = request()->header('user-agent');
        if (strstr($agent, 'WindowsWechat')) {
            return "windowsWechat";
        } elseif (strstr($agent, 'MicroMessenger')) {
            return "weixin";
        } elseif (strstr($agent, 'Alipay')) {
            return "alipay";
        } elseif (strstr($agent, 'QQTheme')) {
            return "qq";
        } elseif (strstr($agent, 'aweme app')) {
            return "douyin";
        } else {
            return "pc";
        }
    }
}

if (!function_exists("httpGet")) {
    /**
     * curl get请求
     * @param $url string 请求地址
     * @return bool|string
     */
    function httpGet($url)
    {
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($curl, CURLOPT_TIMEOUT, 500);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
        curl_setopt($curl, CURLOPT_URL, $url);
        $res = curl_exec($curl);
        curl_close($curl);
        return $res;
    }
}

if (!function_exists("httpPost")) {
    /**
     * curl post请求
     * @param $url string 请求地址
     * @param $data array 请求数据
     * @param $json bool 是否json格式
     * @return bool|string
     */
    function httpPost($url, $data, $json = false)
    {
        // 模拟提交数据函数
        $curl = curl_init(); // 启动一个CURL会话
        curl_setopt($curl, CURLOPT_URL, $url); // 要访问的地址
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0); // 对认证证书来源的检查
        curl_setopt($curl, CURLOPT_USERAGENT, request()->header('user-agent') ?? ''); // 模拟用户使用的浏览器
        curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1); // 使用自动跳转
        curl_setopt($curl, CURLOPT_AUTOREFERER, 1); // 自动设置Referer
        if (!$json) {
            curl_setopt($curl, CURLOPT_POST, 1); // 发送一个常规的Post请求
            curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($data)); // Post提交的数据包
        } else {
            if (!empty($data)) {
                if (is_array($data)) {
                    $data = json_encode($data);
                }
                curl_setopt($curl, CURLOPT_POST, 1);
                curl_setopt($curl, CURLOPT_POSTFIELDS, $data);

                // 发送JSON数据
                curl_setopt($curl, CURLOPT_HEADER, 0);
                curl_setopt($curl, CURLOPT_HTTPHEADER,
                    array(
                        'Content-Type: application/json; charset=utf-8',
                        'Content-Length:' . strlen($data)
                    ));
            }
        }
        curl_setopt($curl, CURLOPT_TIMEOUT, 30); // 设置超时限制防止死循环
        curl_setopt($curl, CURLOPT_HEADER, 0); // 显示返回的Header区域内容
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); // 获取的信息以文件流的形式返回
        $response = curl_exec($curl); // 执行操作
        if (curl_errno($curl)) {
            echo 'Errno' . curl_error($curl);
            return false;
        }
        curl_close($curl); // 关键CURL会话
        return $response; // 返回数据
    }
}

if (!function_exists("get_ip")) {
    /**
     * 获取客户端ip
     * @return mixed|string
     */
    function get_ip()
    {
        return request()->ip();
    }
}

if (!function_exists("hide_str")) {

    /**
     * 字符串隐藏
     * @param $string
     * @param int $bengin 起始位置
     * @param int $len 星号长度
     * @param int $type 0左向右，1右向左，2保留首尾
     * @param int $num 星号个数，仅type2生效
     * @return string
     */
    function hide_str($string, $bengin = 4, $len = 4, $type = 2, $num = 8)
    {
        $array = array();
        $strlen = $length = mb_strlen($string);
        while ($strlen) {
            $array[] = mb_substr($string, 0, 1, "utf8");
            $string = mb_substr($string, 1, $strlen, "utf8");
            $strlen = mb_strlen($string);
        }
        switch ($type) {
            case 0:
                for ($i = $bengin; $i < ($bengin + $len); $i++) {
                    if (isset($array[$i]))
                        $array[$i] = "*";
                }
                $string = implode("", $array);
                break;
            case 1:
                $array = array_reverse($array);
                for ($i = $bengin; $i < ($bengin + $len); $i++) {
                    if (isset($array[$i]))
                        $array[$i] = "*";
                }
                $string = implode("", array_reverse($array));
                break;
            case 2:
                $left = $bengin;
                $right = $len;
                $tem = array();
                $_num = $num;
                for ($i = 0; $i < ($length - $right); $i++) {
                    if (isset($array[$i])) {
                        $str = $i >= $left ? "*" : $array[$i];
                        if ($str == "*" && $_num > 0) {
                            $num--;
                            if ($num < 0) {
                                continue;
                            }
                        }
                        $tem[] = $str;
                    }
                }
                $array = array_chunk(array_reverse($array), $right);
                $array = array_reverse($array[0]);
                for ($i = 0; $i < $right; $i++) {
                    $tem[] = $array[$i];
                }
                $string = implode("", $tem);
                break;
        }
        return $string;
    }
}

if (!function_exists("down_file")) {
    /**
     * 下载程序压缩包文件
     * @param string $url 要下载的url
     * @param string $save_dir 要存放的目录
     * @return boolean res 成功返回下载信息 失败返回false
     */
    function down_file($url, $save_dir)
    {
        if (trim($url) == '') {
            return false;
        }
        if (trim($save_dir) == '') {
            return false;
        }
        if (0 !== strrpos($save_dir, '/')) {
            $save_dir .= '/';
        }
        $filename = basename($url);
        //创建保存目录
        if (!file_exists($save_dir) && !mkdir($save_dir, 0777, true)) {
            return false;
        }
        //开始下载
        $ch = curl_init();
        $timeout = 5;
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
        $content = curl_exec($ch);
        $status = curl_getinfo($ch);
        curl_close($ch);

        // 判断执行结果
        if ($status['http_code'] == 200) {
            $size = strlen($content);
            //文件大小
            $fp2 = @fopen($save_dir . $filename, 'a');
            fwrite($fp2, $content);
            fclose($fp2);
            unset($content, $url);
            $res = [
                'status'    => $status['http_code'],
                'file_name' => $filename,
                'save_path' => $save_dir . $filename
            ];
        } else {
            $res = false;
        }

        return $res;
    }
}

if (!function_exists("deal_zip")) {
    /**
     * 解压缩
     * @param $file string 要解压的文件
     * @param $todir string 要存放的目录
     * @return int 包含所有文件及目录的数组
     */
    function deal_zip($file, $todir)
    {
        if (trim($file) == '') {
            return 406;
        }
        if (trim($todir) == '') {
            return 406;
        }
        $zip = new \ZipArchive;
        // 中文文件名要使用ANSI编码的文件格式
        if ($zip->open($file) === TRUE) {
            //提取全部文件
            $zip->extractTo($todir);
            $zip->close();
            $result = 200;
        } else {
            $result = 406;
        }
        return $result;
    }
}

if (!function_exists("dealWithDiyData")) {
    /**
     * 处理Diy数据
     * @param $data
     * @return mixed
     */
    function dealWithDiyData($data)
    {
        $rule = $data['rule'] ?? [];
        $data['rule'] = dealWithRule($rule);
        return $data;
    }
}

if (!function_exists("dealWithRule")) {
    /**
     * 处理Diy的Rule数据
     * @param $rule
     * @return array
     */
    function dealWithRule($rule)
    {
        $dk_rule = [];
        foreach ($rule as $key => $value) {
            if (isset($value['type']) && $value['type'] == 'vanCol') {
                if (isset($value['children'])) {
                    $value['children'] = dealWithRule($value['children']);
                }
                $dk_rule[$key] = $value;
            } else {
                if (isset($value['children'])) {
                    $value['children'] = dealWithRule($value['children']);
                }
                $dk_rule[$key] = array(
                    'display'  => true,
                    'hidden'   => false,
                    'props'    => ['setting' => $value['setting'] ?? []],
                    'type'     => "dkRow",
                    'children' => [$value]
                );
            }
        }
        return $dk_rule;
    }
}

if (!function_exists("getFormData")) {
    /**
     * 获取表单数据
     * @param $key
     * @param $prefix
     * @param $formData
     * @return array|mixed
     */
    function getFormData($key = 'formData', $prefix = 'config', $formData = [])
    {
        if (!$formData) {
            $formData = input($key, []);
        }
        if (is_array($prefix)) {
            foreach ($prefix as $key => $_prefix) {
                foreach ($formData as $k => $value) {
                    if (strpos($k, $_prefix . "_") === 0) {
                        $formData[$_prefix][str_replace($_prefix . "_", "", $k)] = $value;
                        unset($formData[$k]);
                    }
                }
            }
        } else {
            foreach ($formData as $k => $value) {
                if (strpos($k, $prefix . "_") === 0) {
                    $formData[$prefix][str_replace($prefix . "_", "", $k)] = $value;
                    unset($formData[$k]);
                }
            }
        }
        return $formData;
    }
}

if (!function_exists("showMessage")) {
    /**
     * @param string $message 文字说明
     * @param string $type 类型 error,warning,info,success，可以直接传入图片
     * @param string $url 地址，不填为返回上一页
     * @param array $config 配置项，自己看代码
     */
    function showMessage($message = '', $type = 'info', $url = '', $code = -1, $config = [])
    {
        throw new MessageException($message, $type, $url, $code, $config);
    }
}

if (!function_exists("getPlatformAddonConfig")) {
    /**
     * 获取平台应用配置
     * @param $addon_name
     * @param $plaid
     * @return array|mixed
     */
    function getPlatformAddonConfig($addon_name = '', $plaid = 0)
    {
        return (new PlatformAddon())->getPlatformAddonConfig($addon_name, $plaid);
    }
}

if (!function_exists("getPlatformAppConfig")) {
    /**
     * 获取平台应用配置
     * @param $addon_name
     * @param $plaid
     * @return array|mixed
     */
    function getPlatformAppConfig($addon_name = '', $appid = 0)
    {
        return (new PlatformApp())->getPlatformAppConfig($addon_name, $appid);
    }
}

if (!function_exists("getAddonConfig")) {
    /**
     * 获取应用配置
     * @param $addon_name
     * @return mixed
     */
    function getAddonConfig($addon_name = '')
    {
        $addon_name = $addon_name ?: get_addon();
        $res = (new Addons())->where(['name' => $addon_name])->value('config');
        return json_decode($res, true);
    }
}

if (!function_exists("exist_field")) {

    /**
     * 验证表的字段是否存在
     * @param $table
     * @param $field
     * @return bool
     */
    function exist_field($table, $field)
    {
        $fields = DB::name($table)->getFields();
        return isset($fields[$field]) ? true : false;
    }
}

if (!function_exists("dk_query")) {
    /**
     * 执行sql
     * @param string $sql
     */
    function dk_query($sql = "")
    {
        Addons::batchSql($sql);
    }
}

if (!function_exists("table")) {

    /**
     * 得到当前或者指定名称的数据表
     * @param $name
     * @return mixed|string
     */
    function table($name)
    {
        return DB::name($name)->getTable();
    }
}

if (!function_exists("drop_table")) {

    /**
     * 删除数据表
     * @param $table_name string 表名 无需前缀
     * @return mixed
     */
    function drop_table($table_name)
    {
        return Addons::dropTable($table_name);
    }
}

if (!function_exists('getJssdk')) {
    function getJssdk($debug = false, $jsApiList = [])
    {
        return Ws::getJssdk($debug, $jsApiList);
    }
}
if (!function_exists('getShare')) {
    function getShare($share = [], $fun = '')
    {
        return Ws::getShare($share, $fun);
    }
}
if (!function_exists('getWxUser')) {
    function getWxUser()
    {
        return Ws::getUser();
    }
}
if (!function_exists('getDomain')) {
    function getDomain()
    {
        $preference = (new PlatformSetting())->getValueByKey("preference", get_plaid());
        $res = array(
            'oauth' => $preference['oauth_domain'] ?? '',
            'share' => $preference['share_domain'] ?? '',
            'die'   => $preference['die_domain'] ?? '',
        );
        return $res;
    }
}
if (!function_exists('isSwoole')) {
    function isSwoole()
    {
        return get_class(app()) == 'think\swoole\App';
    }
}
